- 1 Tabulate a sum list of all RNA and smallRNA counts by cell line/treatment type
- 2 Add MIMAT ID to small RNAseq data
- 3 Beginning with sensitive cell lines, creating a count table of miRNA, mRNA, and hybrids
- 4 Create a generalized match list that will merge all datasets eventually
- 5 Count hybrids, add to match list
- 6 Count small RNAseq data, add to match list
- 7 Count total RNAseq data, add to match list
- 8 Repeat the above steps, using resistant cell line data
- 9 Create a generalized match list that will merge all datasets eventually
- 10 Count hybrids, add to match list
- 11 Count small RNAseq data, add to match list
- 12 Count total RNAseq data, add to match list
- 13 Merge all dataframes to create a singular count table of all cell lines and treatments
- 14 Create a count of whether hybrids are seen in triplicates, duplicates, or as unique hybrids
- 15 Create a 3D Representation of the log Value of Counts
hyb_sensitive <- readRDS(here::here("initial_data/hyb_sensitive.rds"))
hyb_resistant <- readRDS(here::here("initial_data/hyb_resistant.rds"))
totalRNA_count <- readRDS(here::here("initial_data/totalRNA_count.rds"))
smallRNA_count <- readRDS(here::here("initial_data/smallRNA_count.rds"))
totalRNAseq <- readRDS(here::here("initial_data/total_RNAseq_all_annot_results.rds"))
DEGs_smallRNAseq <- readRDS(here::here("initial_data/DEGs_smallRNAseq.rds"))
Tabulate a sum list of all RNA and smallRNA counts by cell line/treatment type
totalRNA_count$IPC_sum <- rowSums(totalRNA_count[ , c(3:5,21:23)], na.rm=TRUE)
totalRNA_count$IPC_R_sum <- rowSums(totalRNA_count[ , c(6:8, 24:26)], na.rm=TRUE)
totalRNA_count$MJ_sum <- rowSums(totalRNA_count[ , c(9:11,27:29)], na.rm=TRUE)
totalRNA_count$MJ_R_sum <- rowSums(totalRNA_count[ , c(12:14, 30:32)], na.rm=TRUE)
totalRNA_count$SK_sum <- rowSums(totalRNA_count[ , c(15:17, 33:35)], na.rm=TRUE)
totalRNA_count$SK_R_sum <- rowSums(totalRNA_count[ , c(18:20,36:38)], na.rm=TRUE)
totalRNA_sum <- totalRNA_count[,c(1,2,39:44)]
names(totalRNA_sum)[names(totalRNA_sum) == 'gene_name'] <- 'mRNA'
#saveRDS(totalRNA_sum, "totalRNA_sum.RDS")
smallRNA_count$IPC_sum <- rowSums(smallRNA_count[ , c(3:5)], na.rm=TRUE)
smallRNA_count$IPC_R_sum <- rowSums(smallRNA_count[ , c(6:8)], na.rm=TRUE)
smallRNA_count$MJ_sum <- rowSums(smallRNA_count[ , c(9:11)], na.rm=TRUE)
smallRNA_count$MJ_R_sum <- rowSums(smallRNA_count[ , c(12:14)], na.rm=TRUE)
smallRNA_count$SK_sum <- rowSums(smallRNA_count[ , c(15:17)], na.rm=TRUE)
smallRNA_count$SK_R_sum <- rowSums(smallRNA_count[ , c(18:20)], na.rm=TRUE)
smallRNA_sum <- smallRNA_count[, c(1,20:25)]
#saveRDS(smallRNA_sum, "smallRNA_sum.RDS")
miRNANames = smallRNA_sum$Molecule
smallRNA_sum2 <- miRNA_NameToAccession(miRNANames,version = "v18")
names(smallRNA_sum2)[names(smallRNA_sum2) == 'miRNAName_v18'] <- 'Molecule'
smallRNA_sum <- merge(smallRNA_sum, smallRNA_sum2, by = "Molecule")
names(smallRNA_sum)[names(smallRNA_sum) == 'Accession'] <- 'MIMAT'
#smallRNA_sum <- smallRNA_sum[, c(1, 20, 2:19)]
Add MIMAT ID to small RNAseq data
DEGs_smallRNAseq$gene_name = paste('hsa', DEGs_smallRNAseq$gene_name, sep='-')
miRNANames = DEGs_smallRNAseq$gene_name
DEGs_smallRNAseq2 <- miRNA_NameToAccession(miRNANames,version = "v18")
names(DEGs_smallRNAseq2)[names(DEGs_smallRNAseq2) == 'miRNAName_v18'] <- 'gene_name'
DEGs_smallRNAseq2 <- distinct(DEGs_smallRNAseq2, gene_name, .keep_all = TRUE)
DEGs_smallRNAseq <- merge(DEGs_smallRNAseq, DEGs_smallRNAseq2, by = "gene_name")
names(DEGs_smallRNAseq)[names(DEGs_smallRNAseq) == 'Accession'] <- 'MIMAT'
#saveRDS(DEGs_smallRNAseq, "MIMAT_smallRNA_DEGs.rds")
Beginning with sensitive cell lines, creating a count table of miRNA, mRNA, and hybrids
Create a generalized match list that will merge all datasets eventually
ipc_hybrids <- hyb_sensitive %>% filter(grepl("IPC", Sample))
sk_hybrids <- hyb_sensitive %>% filter(grepl("SK", Sample))
mj_hybrids <- hyb_sensitive %>% filter(grepl("MJ", Sample))
ipc_match_list <- select(ipc_hybrids, miRNA, MIMAT, mRNA, hybrids)
sk_match_list <- select(sk_hybrids, miRNA, MIMAT, mRNA, hybrids)
mj_match_list <- select(mj_hybrids, miRNA, MIMAT, mRNA, hybrids)
ipc_match_list <- distinct(ipc_match_list, hybrids, .keep_all = TRUE)
sk_match_list <- distinct(sk_match_list, hybrids, .keep_all = TRUE)
mj_match_list <- distinct(mj_match_list, hybrids, .keep_all = TRUE)
Count hybrids, add to match list
IPC_hyb <- ipc_hybrids %>%
group_by(hybrids) %>%
tally(sort = TRUE)
ipc_match_list <- merge(ipc_match_list, IPC_hyb, by = 'hybrids', .keep_all = TRUE)
SK_hyb <- sk_hybrids %>%
group_by(hybrids) %>%
tally(sort = TRUE)
sk_match_list <- merge(sk_match_list, SK_hyb, by = "hybrids", .keep_all = TRUE)
MJ_hyb <- mj_hybrids %>%
group_by(hybrids) %>%
tally(sort = TRUE)
mj_match_list <- merge(mj_match_list, MJ_hyb, by = "hybrids", .keep_all = TRUE)
Count small RNAseq data, add to match list
IPC_smallRNA <- smallRNA_sum[, c(2,8)]
ipc_match_list <- merge(ipc_match_list, IPC_smallRNA, by = 'MIMAT', .keep_all = TRUE)
names(ipc_match_list)[names(ipc_match_list) == 'IPC_sum'] <- 'miRNA_count'
names(ipc_match_list)[names(ipc_match_list) == 'n'] <- 'hybrid_count'
sk_smallRNA <- smallRNA_sum[, c(6,8)]
sk_match_list <- merge(sk_match_list, sk_smallRNA, by = 'MIMAT', .keep_all = TRUE)
names(sk_match_list)[names(sk_match_list) == 'SK_sum'] <- 'miRNA_count'
names(sk_match_list)[names(sk_match_list) == 'n'] <- 'hybrid_count'
mj_smallRNA <- smallRNA_sum[, c(4,8)]
mj_match_list <- merge(mj_match_list, mj_smallRNA, by = 'MIMAT', .keep_all = TRUE)
names(mj_match_list)[names(mj_match_list) == 'MJ_sum'] <- 'miRNA_count'
names(mj_match_list)[names(mj_match_list) == 'n'] <- 'hybrid_count'
Count total RNAseq data, add to match list
IPC_totalRNA <- totalRNA_sum[, c(1,2,3)]
ipc_match_list <- merge(ipc_match_list, IPC_totalRNA, by = "mRNA", .keep_all = TRUE)
names(ipc_match_list)[names(ipc_match_list) == 'IPC_sum'] <- 'mRNA_count'
ipc_match_list$cell_line <- "IPC"
ipc_match_list$treatment <- "sensitive"
ipc_match_list <- ipc_match_list[, c(9,10,3,1,7,4,2,5,8,6)]
#saveRDS(ipc_match_list, "IPC_data.RDS")
sk_totalRNA <- totalRNA_sum[, c(1,2,7)]
sk_match_list <- merge(sk_match_list, sk_totalRNA, by = "mRNA", .keep_all = TRUE)
names(sk_match_list)[names(sk_match_list) == 'SK_sum'] <- 'mRNA_count'
sk_match_list$cell_line <- "SK"
sk_match_list$treatment <- "sensitive"
sk_match_list <- sk_match_list[, c(9,10,3,1,7,4,2,5,8,6)]
#saveRDS(sk_match_list, "SK_data.RDS")
mj_totalRNA <- totalRNA_sum[, c(1,2,5)]
mj_match_list <- merge(mj_match_list, mj_totalRNA, by = "mRNA", .keep_all = TRUE)
names(mj_match_list)[names(mj_match_list) == 'MJ_sum'] <- 'mRNA_count'
mj_match_list$cell_line <- "MJ"
mj_match_list$treatment <- "sensitive"
mj_match_list <- mj_match_list[, c(9,10,3,1,7,4,2,5,8,6)]
#saveRDS(mj_match_list, "MJ_data.RDS")
Repeat the above steps, using resistant cell line data
Create a generalized match list that will merge all datasets eventually
ipc_R_hybrids <- hyb_resistant %>% filter(grepl("IPC", Sample))
sk_R_hybrids <- hyb_resistant %>% filter(grepl("SK", Sample))
ipc_R_match_list <- select(ipc_R_hybrids, miRNA, MIMAT, mRNA, hybrids)
sk_R_match_list <- select(sk_R_hybrids, miRNA, MIMAT, mRNA, hybrids)
ipc_R_match_list <- distinct(ipc_R_match_list, hybrids, .keep_all = TRUE)
sk_R_match_list <- distinct(sk_R_match_list, hybrids, .keep_all = TRUE)
Count hybrids, add to match list
IPC_R_hyb <- ipc_R_hybrids %>%
group_by(hybrids) %>%
tally(sort = TRUE)
SK_R_hyb <- sk_R_hybrids %>%
group_by(hybrids) %>%
tally(sort = TRUE)
ipc_R_match_list <- merge(ipc_R_match_list, IPC_R_hyb, by = 'hybrids', .keep_all = TRUE)
sk_R_match_list <- merge(sk_R_match_list, SK_R_hyb, by = "hybrids", .keep_all = TRUE)
Count small RNAseq data, add to match list
IPC_R_smallRNA <- smallRNA_sum[, c(3,8)]
ipc_R_match_list <- merge(ipc_R_match_list, IPC_R_smallRNA, by = 'MIMAT', .keep_all = TRUE)
names(ipc_R_match_list)[names(ipc_R_match_list) == 'IPC_R_sum'] <- 'miRNA_count'
names(ipc_R_match_list)[names(ipc_R_match_list) == 'n'] <- 'hybrid_count'
#saveRDS(ipc_R_match_list, "IPC_R_data.RDS")
sk_R_smallRNA <- smallRNA_sum[, c(7,8)]
sk_R_match_list <- merge(sk_R_match_list, sk_R_smallRNA, by = 'MIMAT', .keep_all = TRUE)
names(sk_R_match_list)[names(sk_R_match_list) == 'SK_R_sum'] <- 'miRNA_count'
names(sk_R_match_list)[names(sk_R_match_list) == 'n'] <- 'hybrid_count'
#saveRDS(sk_R_match_list, "SK_R_data.RDS")
Count total RNAseq data, add to match list
IPC_R_totalRNA <- totalRNA_sum[, c(1,2,4)]
ipc_R_match_list <- merge(ipc_R_match_list, IPC_R_totalRNA, by = "mRNA", .keep_all = TRUE)
names(ipc_R_match_list)[names(ipc_R_match_list) == 'IPC_R_sum'] <- 'mRNA_count'
ipc_R_match_list$cell_line <- "IPC_R"
ipc_R_match_list$treatment <- "resistant"
ipc_R_match_list <- ipc_R_match_list[, c(9,10,3,1,7,4,2,5,8,6)]
#saveRDS(ipc_R_match_list, "IPC_R_data.RDS")
sk_R_totalRNA <- totalRNA_sum[, c(1,2,8)]
sk_R_match_list <- merge(sk_R_match_list, sk_R_totalRNA, by = "mRNA", .keep_all = TRUE)
names(sk_R_match_list)[names(sk_R_match_list) == 'SK_R_sum'] <- 'mRNA_count'
sk_R_match_list$cell_line <- "SK_R"
sk_R_match_list$treatment <- "resistant"
sk_R_match_list <- sk_R_match_list[, c(9,10,3,1,7,4,2,5,8,6)]
#saveRDS(sk_R_match_list, "SK_R_data.RDS")
Merge all dataframes to create a singular count table of all cell lines and treatments
#SK_R_data <- readRDS("SK_R_data.rds")
#SK_data <- readRDS("SK_data.rds")
#IPC_R_data <- readRDS("IPC_R_data.rds")
#IPC_data <- readRDS("IPC_data.rds")
#MJ_data <- readRDS("MJ_data.RDS")
#count_data <- rbind(SK_R_data, SK_data, IPC_R_data, IPC_data, MJ_data)
count_data <- rbind(sk_R_match_list, sk_match_list, ipc_R_match_list, ipc_match_list, mj_match_list)
#saveRDS(count_data, "total_count_data.rds")
Create a count of whether hybrids are seen in triplicates, duplicates, or as unique hybrids
qCLASH <- bind_rows(readRDS(here::here("initial_data/hyb_sensitive.rds")) %>%
mutate(condition="sensitive") ,
readRDS(here::here("initial_data/hyb_resistant.rds")) %>%
mutate(condition="resistant"))
counts_replicates <- qCLASH %>%
group_by(condition, cell_line, hybrids) %>%
summarise(replicates = list(Sample %>% unique()), miRNA, mRNA ) %>%
mutate(total = map_int( replicates, length)) %>%
distinct() %>%
mutate(in_triplicates = factor(ifelse(total==3, "Triplicates",
ifelse(total==2, "Duplicates", "Unique")),
levels = c("Unique", "Duplicates", "Triplicates"))) %>%
arrange(condition, cell_line, hybrids, in_triplicates) %>%
ungroup() %>%
right_join(count_data, by=c("cell_line", "hybrids", "mRNA", "miRNA"))
`summarise()` has grouped output by 'condition', 'cell_line', 'hybrids'. You can override using the `.groups` argument.
Create a 3D Representation of the log Value of Counts
fig <- plot_ly(count_data, x = ~log(mRNA_count), y = ~log(hybrid_count), z = ~log(miRNA_count), color = ~cell_line, colors = c('dodgerblue4', 'darkslategray4','darkgreen', 'firebrick', 'darksalmon'))
fig <- fig %>% add_markers()
fig <- fig %>% layout(scene = list(xaxis = list(title = 'Log(mRNA Count)'),
yaxis = list(title = 'Log(Hybrid Count)'),
zaxis = list(title = 'Log(miRNA Count)')),
title='Correlation Analysis')
fig
htmlwidgets::saveWidget(plotly::as_widget(fig), "./results/qCLASH_tot_RNAseq_spatial_representation.html")
p <- counts_replicates %>%
plotly::plot_ly(x=~log(mRNA_count), y=~log(hybrid_count), z=~log(miRNA_count), size=1, color=~in_triplicates, text=~hybrids, type="scatter3d", mode="markers")
p
htmlwidgets::saveWidget(plotly::as_widget(p), "./results/qCLASH_tot_RNAseq_triplicates.html")
LS0tDQp0aXRsZTogIkRhdGEgQ291bnRzIGFuZCBWaXN1YWxpemF0aW9uIg0KYXV0aG9yOiAiVmluY2VudCBHdXJlZ2hpYW4sIEFudGhvdWxhIEdhaWduZWF1eCwgSGFpbGVlIEhlcmJzdCINCmRhdGU6ICI0LzQvMjAyMiINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazoNCiAgICBoaWdobGlnaHQ6IGRlZmF1bHQNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRoZW1lOiB1bml0ZWQNCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogMg0KICAgIGNvZGU6IGhpZGUNCiAgcGRmX2RvY3VtZW50Og0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBmaWdfY3JvcDogbm8NCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvYzogeWVzDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCiAgICBkZl9wcmludDogcGFnZWQNCi0tLQ0KDQoNCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoZ2dwdWJyKQ0KbGlicmFyeShyZ2wpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHBsb3QzRCkNCmxpYnJhcnkocmVzaGFwZTIpDQpsaWJyYXJ5KG1ldFIpDQpsaWJyYXJ5KG1pUkJhc2VDb252ZXJ0ZXIpDQpgYGANCg0KDQpgYGB7cn0NCmh5Yl9zZW5zaXRpdmUgPC0gcmVhZFJEUyhoZXJlOjpoZXJlKCJpbml0aWFsX2RhdGEvaHliX3NlbnNpdGl2ZS5yZHMiKSkNCmh5Yl9yZXNpc3RhbnQgPC0gcmVhZFJEUyhoZXJlOjpoZXJlKCJpbml0aWFsX2RhdGEvaHliX3Jlc2lzdGFudC5yZHMiKSkNCnRvdGFsUk5BX2NvdW50IDwtIHJlYWRSRFMoaGVyZTo6aGVyZSgiaW5pdGlhbF9kYXRhL3RvdGFsUk5BX2NvdW50LnJkcyIpKQ0Kc21hbGxSTkFfY291bnQgPC0gcmVhZFJEUyhoZXJlOjpoZXJlKCJpbml0aWFsX2RhdGEvc21hbGxSTkFfY291bnQucmRzIikpDQp0b3RhbFJOQXNlcSA8LSByZWFkUkRTKGhlcmU6OmhlcmUoImluaXRpYWxfZGF0YS90b3RhbF9STkFzZXFfYWxsX2Fubm90X3Jlc3VsdHMucmRzIikpDQpERUdzX3NtYWxsUk5Bc2VxIDwtIHJlYWRSRFMoaGVyZTo6aGVyZSgiaW5pdGlhbF9kYXRhL0RFR3Nfc21hbGxSTkFzZXEucmRzIikpDQpgYGANCg0KDQojIFRhYnVsYXRlIGEgc3VtIGxpc3Qgb2YgYWxsIFJOQSBhbmQgc21hbGxSTkEgY291bnRzIGJ5IGNlbGwgbGluZS90cmVhdG1lbnQgdHlwZQ0KYGBge3J9DQp0b3RhbFJOQV9jb3VudCRJUENfc3VtIDwtIHJvd1N1bXModG90YWxSTkFfY291bnRbICwgYygzOjUsMjE6MjMpXSwgbmEucm09VFJVRSkNCnRvdGFsUk5BX2NvdW50JElQQ19SX3N1bSA8LSByb3dTdW1zKHRvdGFsUk5BX2NvdW50WyAsIGMoNjo4LCAyNDoyNildLCBuYS5ybT1UUlVFKQ0KdG90YWxSTkFfY291bnQkTUpfc3VtIDwtIHJvd1N1bXModG90YWxSTkFfY291bnRbICwgYyg5OjExLDI3OjI5KV0sIG5hLnJtPVRSVUUpDQp0b3RhbFJOQV9jb3VudCRNSl9SX3N1bSA8LSByb3dTdW1zKHRvdGFsUk5BX2NvdW50WyAsIGMoMTI6MTQsIDMwOjMyKV0sIG5hLnJtPVRSVUUpDQp0b3RhbFJOQV9jb3VudCRTS19zdW0gPC0gcm93U3Vtcyh0b3RhbFJOQV9jb3VudFsgLCBjKDE1OjE3LCAzMzozNSldLCBuYS5ybT1UUlVFKQ0KdG90YWxSTkFfY291bnQkU0tfUl9zdW0gPC0gcm93U3Vtcyh0b3RhbFJOQV9jb3VudFsgLCBjKDE4OjIwLDM2OjM4KV0sIG5hLnJtPVRSVUUpDQp0b3RhbFJOQV9zdW0gPC0gdG90YWxSTkFfY291bnRbLGMoMSwyLDM5OjQ0KV0NCm5hbWVzKHRvdGFsUk5BX3N1bSlbbmFtZXModG90YWxSTkFfc3VtKSA9PSAnZ2VuZV9uYW1lJ10gPC0gJ21STkEnDQojc2F2ZVJEUyh0b3RhbFJOQV9zdW0sICJ0b3RhbFJOQV9zdW0uUkRTIikNCg0Kc21hbGxSTkFfY291bnQkSVBDX3N1bSA8LSByb3dTdW1zKHNtYWxsUk5BX2NvdW50WyAsIGMoMzo1KV0sIG5hLnJtPVRSVUUpDQpzbWFsbFJOQV9jb3VudCRJUENfUl9zdW0gPC0gcm93U3VtcyhzbWFsbFJOQV9jb3VudFsgLCBjKDY6OCldLCBuYS5ybT1UUlVFKQ0Kc21hbGxSTkFfY291bnQkTUpfc3VtIDwtIHJvd1N1bXMoc21hbGxSTkFfY291bnRbICwgYyg5OjExKV0sIG5hLnJtPVRSVUUpDQpzbWFsbFJOQV9jb3VudCRNSl9SX3N1bSA8LSByb3dTdW1zKHNtYWxsUk5BX2NvdW50WyAsIGMoMTI6MTQpXSwgbmEucm09VFJVRSkNCnNtYWxsUk5BX2NvdW50JFNLX3N1bSA8LSByb3dTdW1zKHNtYWxsUk5BX2NvdW50WyAsIGMoMTU6MTcpXSwgbmEucm09VFJVRSkNCnNtYWxsUk5BX2NvdW50JFNLX1Jfc3VtIDwtIHJvd1N1bXMoc21hbGxSTkFfY291bnRbICwgYygxODoyMCldLCBuYS5ybT1UUlVFKQ0Kc21hbGxSTkFfc3VtIDwtIHNtYWxsUk5BX2NvdW50WywgYygxLDIwOjI1KV0NCiNzYXZlUkRTKHNtYWxsUk5BX3N1bSwgInNtYWxsUk5BX3N1bS5SRFMiKQ0KDQoNCm1pUk5BTmFtZXMgPSBzbWFsbFJOQV9zdW0kTW9sZWN1bGUNCnNtYWxsUk5BX3N1bTIgPC0gbWlSTkFfTmFtZVRvQWNjZXNzaW9uKG1pUk5BTmFtZXMsdmVyc2lvbiA9ICJ2MTgiKQ0KbmFtZXMoc21hbGxSTkFfc3VtMilbbmFtZXMoc21hbGxSTkFfc3VtMikgPT0gJ21pUk5BTmFtZV92MTgnXSA8LSAnTW9sZWN1bGUnDQpzbWFsbFJOQV9zdW0gPC0gbWVyZ2Uoc21hbGxSTkFfc3VtLCBzbWFsbFJOQV9zdW0yLCBieSA9ICJNb2xlY3VsZSIpDQpuYW1lcyhzbWFsbFJOQV9zdW0pW25hbWVzKHNtYWxsUk5BX3N1bSkgPT0gJ0FjY2Vzc2lvbiddIDwtICdNSU1BVCcNCiNzbWFsbFJOQV9zdW0gPC0gc21hbGxSTkFfc3VtWywgYygxLCAyMCwgMjoxOSldDQoNCmBgYA0KDQoNCiMgQWRkIE1JTUFUIElEIHRvIHNtYWxsIFJOQXNlcSBkYXRhDQpgYGB7cn0NCkRFR3Nfc21hbGxSTkFzZXEkZ2VuZV9uYW1lID0gcGFzdGUoJ2hzYScsIERFR3Nfc21hbGxSTkFzZXEkZ2VuZV9uYW1lLCBzZXA9Jy0nKQ0KDQptaVJOQU5hbWVzID0gREVHc19zbWFsbFJOQXNlcSRnZW5lX25hbWUNCkRFR3Nfc21hbGxSTkFzZXEyIDwtIG1pUk5BX05hbWVUb0FjY2Vzc2lvbihtaVJOQU5hbWVzLHZlcnNpb24gPSAidjE4IikNCg0KbmFtZXMoREVHc19zbWFsbFJOQXNlcTIpW25hbWVzKERFR3Nfc21hbGxSTkFzZXEyKSA9PSAnbWlSTkFOYW1lX3YxOCddIDwtICdnZW5lX25hbWUnDQpERUdzX3NtYWxsUk5Bc2VxMiA8LSBkaXN0aW5jdChERUdzX3NtYWxsUk5Bc2VxMiwgZ2VuZV9uYW1lLCAua2VlcF9hbGwgPSBUUlVFKQ0KREVHc19zbWFsbFJOQXNlcSA8LSBtZXJnZShERUdzX3NtYWxsUk5Bc2VxLCBERUdzX3NtYWxsUk5Bc2VxMiwgYnkgPSAiZ2VuZV9uYW1lIikNCg0KbmFtZXMoREVHc19zbWFsbFJOQXNlcSlbbmFtZXMoREVHc19zbWFsbFJOQXNlcSkgPT0gJ0FjY2Vzc2lvbiddIDwtICdNSU1BVCcNCiNzYXZlUkRTKERFR3Nfc21hbGxSTkFzZXEsICJNSU1BVF9zbWFsbFJOQV9ERUdzLnJkcyIpDQpgYGANCg0KDQojIEJlZ2lubmluZyB3aXRoIHNlbnNpdGl2ZSBjZWxsIGxpbmVzLCBjcmVhdGluZyBhIGNvdW50IHRhYmxlIG9mIG1pUk5BLCBtUk5BLCBhbmQgaHlicmlkcw0KDQojIENyZWF0ZSBhIGdlbmVyYWxpemVkIG1hdGNoIGxpc3QgdGhhdCB3aWxsIG1lcmdlIGFsbCBkYXRhc2V0cyBldmVudHVhbGx5DQpgYGB7cn0NCmlwY19oeWJyaWRzIDwtIGh5Yl9zZW5zaXRpdmUgJT4lIGZpbHRlcihncmVwbCgiSVBDIiwgU2FtcGxlKSkNCnNrX2h5YnJpZHMgPC0gaHliX3NlbnNpdGl2ZSAlPiUgZmlsdGVyKGdyZXBsKCJTSyIsIFNhbXBsZSkpDQptal9oeWJyaWRzIDwtIGh5Yl9zZW5zaXRpdmUgJT4lIGZpbHRlcihncmVwbCgiTUoiLCBTYW1wbGUpKQ0KDQppcGNfbWF0Y2hfbGlzdCA8LSBzZWxlY3QoaXBjX2h5YnJpZHMsIG1pUk5BLCBNSU1BVCwgbVJOQSwgaHlicmlkcykgDQpza19tYXRjaF9saXN0IDwtIHNlbGVjdChza19oeWJyaWRzLCBtaVJOQSwgTUlNQVQsIG1STkEsIGh5YnJpZHMpDQptal9tYXRjaF9saXN0IDwtIHNlbGVjdChtal9oeWJyaWRzLCBtaVJOQSwgTUlNQVQsIG1STkEsIGh5YnJpZHMpDQoNCmlwY19tYXRjaF9saXN0IDwtIGRpc3RpbmN0KGlwY19tYXRjaF9saXN0LCBoeWJyaWRzLCAua2VlcF9hbGwgPSBUUlVFKQ0Kc2tfbWF0Y2hfbGlzdCA8LSBkaXN0aW5jdChza19tYXRjaF9saXN0LCBoeWJyaWRzLCAua2VlcF9hbGwgPSBUUlVFKQ0KbWpfbWF0Y2hfbGlzdCA8LSBkaXN0aW5jdChtal9tYXRjaF9saXN0LCBoeWJyaWRzLCAua2VlcF9hbGwgPSBUUlVFKQ0KDQpgYGANCg0KDQojIENvdW50IGh5YnJpZHMsIGFkZCB0byBtYXRjaCBsaXN0DQpgYGB7cn0NCklQQ19oeWIgPC0gaXBjX2h5YnJpZHMgJT4lDQogIGdyb3VwX2J5KGh5YnJpZHMpICU+JQ0KICB0YWxseShzb3J0ID0gVFJVRSkNCmlwY19tYXRjaF9saXN0IDwtIG1lcmdlKGlwY19tYXRjaF9saXN0LCBJUENfaHliLCBieSA9ICdoeWJyaWRzJywgLmtlZXBfYWxsID0gVFJVRSkNCg0KU0tfaHliIDwtIHNrX2h5YnJpZHMgJT4lDQogIGdyb3VwX2J5KGh5YnJpZHMpICU+JQ0KICB0YWxseShzb3J0ID0gVFJVRSkNCnNrX21hdGNoX2xpc3QgPC0gbWVyZ2Uoc2tfbWF0Y2hfbGlzdCwgU0tfaHliLCBieSA9ICJoeWJyaWRzIiwgLmtlZXBfYWxsID0gVFJVRSkNCg0KTUpfaHliIDwtIG1qX2h5YnJpZHMgJT4lDQogIGdyb3VwX2J5KGh5YnJpZHMpICU+JQ0KICB0YWxseShzb3J0ID0gVFJVRSkNCm1qX21hdGNoX2xpc3QgPC0gbWVyZ2UobWpfbWF0Y2hfbGlzdCwgTUpfaHliLCBieSA9ICJoeWJyaWRzIiwgLmtlZXBfYWxsID0gVFJVRSkNCmBgYA0KDQoNCiMgQ291bnQgc21hbGwgUk5Bc2VxIGRhdGEsIGFkZCB0byBtYXRjaCBsaXN0DQpgYGB7cn0NCklQQ19zbWFsbFJOQSA8LSBzbWFsbFJOQV9zdW1bLCBjKDIsOCldDQppcGNfbWF0Y2hfbGlzdCA8LSBtZXJnZShpcGNfbWF0Y2hfbGlzdCwgSVBDX3NtYWxsUk5BLCBieSA9ICdNSU1BVCcsIC5rZWVwX2FsbCA9IFRSVUUpDQpuYW1lcyhpcGNfbWF0Y2hfbGlzdClbbmFtZXMoaXBjX21hdGNoX2xpc3QpID09ICdJUENfc3VtJ10gPC0gJ21pUk5BX2NvdW50Jw0KbmFtZXMoaXBjX21hdGNoX2xpc3QpW25hbWVzKGlwY19tYXRjaF9saXN0KSA9PSAnbiddIDwtICdoeWJyaWRfY291bnQnDQoNCnNrX3NtYWxsUk5BIDwtIHNtYWxsUk5BX3N1bVssIGMoNiw4KV0NCnNrX21hdGNoX2xpc3QgPC0gbWVyZ2Uoc2tfbWF0Y2hfbGlzdCwgc2tfc21hbGxSTkEsIGJ5ID0gJ01JTUFUJywgLmtlZXBfYWxsID0gVFJVRSkNCm5hbWVzKHNrX21hdGNoX2xpc3QpW25hbWVzKHNrX21hdGNoX2xpc3QpID09ICdTS19zdW0nXSA8LSAnbWlSTkFfY291bnQnDQpuYW1lcyhza19tYXRjaF9saXN0KVtuYW1lcyhza19tYXRjaF9saXN0KSA9PSAnbiddIDwtICdoeWJyaWRfY291bnQnDQoNCm1qX3NtYWxsUk5BIDwtIHNtYWxsUk5BX3N1bVssIGMoNCw4KV0NCm1qX21hdGNoX2xpc3QgPC0gbWVyZ2UobWpfbWF0Y2hfbGlzdCwgbWpfc21hbGxSTkEsIGJ5ID0gJ01JTUFUJywgLmtlZXBfYWxsID0gVFJVRSkNCm5hbWVzKG1qX21hdGNoX2xpc3QpW25hbWVzKG1qX21hdGNoX2xpc3QpID09ICdNSl9zdW0nXSA8LSAnbWlSTkFfY291bnQnDQpuYW1lcyhtal9tYXRjaF9saXN0KVtuYW1lcyhtal9tYXRjaF9saXN0KSA9PSAnbiddIDwtICdoeWJyaWRfY291bnQnDQpgYGANCg0KDQojIENvdW50IHRvdGFsIFJOQXNlcSBkYXRhLCBhZGQgdG8gbWF0Y2ggbGlzdA0KYGBge3J9DQpJUENfdG90YWxSTkEgPC0gdG90YWxSTkFfc3VtWywgYygxLDIsMyldDQppcGNfbWF0Y2hfbGlzdCA8LSBtZXJnZShpcGNfbWF0Y2hfbGlzdCwgSVBDX3RvdGFsUk5BLCBieSA9ICJtUk5BIiwgLmtlZXBfYWxsID0gVFJVRSkNCm5hbWVzKGlwY19tYXRjaF9saXN0KVtuYW1lcyhpcGNfbWF0Y2hfbGlzdCkgPT0gJ0lQQ19zdW0nXSA8LSAnbVJOQV9jb3VudCcNCmlwY19tYXRjaF9saXN0JGNlbGxfbGluZSA8LSAiSVBDIg0KaXBjX21hdGNoX2xpc3QkdHJlYXRtZW50IDwtICJzZW5zaXRpdmUiDQppcGNfbWF0Y2hfbGlzdCA8LSBpcGNfbWF0Y2hfbGlzdFssIGMoOSwxMCwzLDEsNyw0LDIsNSw4LDYpXQ0KI3NhdmVSRFMoaXBjX21hdGNoX2xpc3QsICJJUENfZGF0YS5SRFMiKQ0KDQpza190b3RhbFJOQSA8LSB0b3RhbFJOQV9zdW1bLCBjKDEsMiw3KV0NCnNrX21hdGNoX2xpc3QgPC0gbWVyZ2Uoc2tfbWF0Y2hfbGlzdCwgc2tfdG90YWxSTkEsIGJ5ID0gIm1STkEiLCAua2VlcF9hbGwgPSBUUlVFKQ0KbmFtZXMoc2tfbWF0Y2hfbGlzdClbbmFtZXMoc2tfbWF0Y2hfbGlzdCkgPT0gJ1NLX3N1bSddIDwtICdtUk5BX2NvdW50Jw0Kc2tfbWF0Y2hfbGlzdCRjZWxsX2xpbmUgPC0gIlNLIg0Kc2tfbWF0Y2hfbGlzdCR0cmVhdG1lbnQgPC0gInNlbnNpdGl2ZSINCnNrX21hdGNoX2xpc3QgPC0gc2tfbWF0Y2hfbGlzdFssIGMoOSwxMCwzLDEsNyw0LDIsNSw4LDYpXQ0KI3NhdmVSRFMoc2tfbWF0Y2hfbGlzdCwgIlNLX2RhdGEuUkRTIikNCg0KbWpfdG90YWxSTkEgPC0gdG90YWxSTkFfc3VtWywgYygxLDIsNSldDQptal9tYXRjaF9saXN0IDwtIG1lcmdlKG1qX21hdGNoX2xpc3QsIG1qX3RvdGFsUk5BLCBieSA9ICJtUk5BIiwgLmtlZXBfYWxsID0gVFJVRSkNCm5hbWVzKG1qX21hdGNoX2xpc3QpW25hbWVzKG1qX21hdGNoX2xpc3QpID09ICdNSl9zdW0nXSA8LSAnbVJOQV9jb3VudCcNCm1qX21hdGNoX2xpc3QkY2VsbF9saW5lIDwtICJNSiINCm1qX21hdGNoX2xpc3QkdHJlYXRtZW50IDwtICJzZW5zaXRpdmUiDQptal9tYXRjaF9saXN0IDwtIG1qX21hdGNoX2xpc3RbLCBjKDksMTAsMywxLDcsNCwyLDUsOCw2KV0NCiNzYXZlUkRTKG1qX21hdGNoX2xpc3QsICJNSl9kYXRhLlJEUyIpDQpgYGANCg0KDQojIFJlcGVhdCB0aGUgYWJvdmUgc3RlcHMsIHVzaW5nIHJlc2lzdGFudCBjZWxsIGxpbmUgZGF0YQ0KDQoNCiMgQ3JlYXRlIGEgZ2VuZXJhbGl6ZWQgbWF0Y2ggbGlzdCB0aGF0IHdpbGwgbWVyZ2UgYWxsIGRhdGFzZXRzIGV2ZW50dWFsbHkNCmBgYHtyfQ0KaXBjX1JfaHlicmlkcyA8LSBoeWJfcmVzaXN0YW50ICU+JSBmaWx0ZXIoZ3JlcGwoIklQQyIsIFNhbXBsZSkpDQpza19SX2h5YnJpZHMgPC0gaHliX3Jlc2lzdGFudCAlPiUgZmlsdGVyKGdyZXBsKCJTSyIsIFNhbXBsZSkpDQoNCmlwY19SX21hdGNoX2xpc3QgPC0gc2VsZWN0KGlwY19SX2h5YnJpZHMsIG1pUk5BLCBNSU1BVCwgbVJOQSwgaHlicmlkcykgDQpza19SX21hdGNoX2xpc3QgPC0gc2VsZWN0KHNrX1JfaHlicmlkcywgbWlSTkEsIE1JTUFULCBtUk5BLCBoeWJyaWRzKQ0KDQppcGNfUl9tYXRjaF9saXN0IDwtIGRpc3RpbmN0KGlwY19SX21hdGNoX2xpc3QsIGh5YnJpZHMsIC5rZWVwX2FsbCA9IFRSVUUpDQpza19SX21hdGNoX2xpc3QgPC0gZGlzdGluY3Qoc2tfUl9tYXRjaF9saXN0LCBoeWJyaWRzLCAua2VlcF9hbGwgPSBUUlVFKQ0KYGBgDQoNCg0KDQojIENvdW50IGh5YnJpZHMsIGFkZCB0byBtYXRjaCBsaXN0DQpgYGB7cn0NCklQQ19SX2h5YiA8LSBpcGNfUl9oeWJyaWRzICU+JQ0KICBncm91cF9ieShoeWJyaWRzKSAlPiUNCiAgdGFsbHkoc29ydCA9IFRSVUUpDQoNClNLX1JfaHliIDwtIHNrX1JfaHlicmlkcyAlPiUNCiAgZ3JvdXBfYnkoaHlicmlkcykgJT4lDQogIHRhbGx5KHNvcnQgPSBUUlVFKQ0KDQppcGNfUl9tYXRjaF9saXN0IDwtIG1lcmdlKGlwY19SX21hdGNoX2xpc3QsIElQQ19SX2h5YiwgYnkgPSAnaHlicmlkcycsIC5rZWVwX2FsbCA9IFRSVUUpDQpza19SX21hdGNoX2xpc3QgPC0gbWVyZ2Uoc2tfUl9tYXRjaF9saXN0LCBTS19SX2h5YiwgYnkgPSAiaHlicmlkcyIsIC5rZWVwX2FsbCA9IFRSVUUpDQpgYGANCg0KDQojIENvdW50IHNtYWxsIFJOQXNlcSBkYXRhLCBhZGQgdG8gbWF0Y2ggbGlzdA0KYGBge3J9DQpJUENfUl9zbWFsbFJOQSA8LSBzbWFsbFJOQV9zdW1bLCBjKDMsOCldDQppcGNfUl9tYXRjaF9saXN0IDwtIG1lcmdlKGlwY19SX21hdGNoX2xpc3QsIElQQ19SX3NtYWxsUk5BLCBieSA9ICdNSU1BVCcsIC5rZWVwX2FsbCA9IFRSVUUpDQpuYW1lcyhpcGNfUl9tYXRjaF9saXN0KVtuYW1lcyhpcGNfUl9tYXRjaF9saXN0KSA9PSAnSVBDX1Jfc3VtJ10gPC0gJ21pUk5BX2NvdW50Jw0KbmFtZXMoaXBjX1JfbWF0Y2hfbGlzdClbbmFtZXMoaXBjX1JfbWF0Y2hfbGlzdCkgPT0gJ24nXSA8LSAnaHlicmlkX2NvdW50Jw0KI3NhdmVSRFMoaXBjX1JfbWF0Y2hfbGlzdCwgIklQQ19SX2RhdGEuUkRTIikNCg0Kc2tfUl9zbWFsbFJOQSA8LSBzbWFsbFJOQV9zdW1bLCBjKDcsOCldDQpza19SX21hdGNoX2xpc3QgPC0gbWVyZ2Uoc2tfUl9tYXRjaF9saXN0LCBza19SX3NtYWxsUk5BLCBieSA9ICdNSU1BVCcsIC5rZWVwX2FsbCA9IFRSVUUpDQpuYW1lcyhza19SX21hdGNoX2xpc3QpW25hbWVzKHNrX1JfbWF0Y2hfbGlzdCkgPT0gJ1NLX1Jfc3VtJ10gPC0gJ21pUk5BX2NvdW50Jw0KbmFtZXMoc2tfUl9tYXRjaF9saXN0KVtuYW1lcyhza19SX21hdGNoX2xpc3QpID09ICduJ10gPC0gJ2h5YnJpZF9jb3VudCcNCiNzYXZlUkRTKHNrX1JfbWF0Y2hfbGlzdCwgIlNLX1JfZGF0YS5SRFMiKQ0KYGBgDQoNCiMgQ291bnQgdG90YWwgUk5Bc2VxIGRhdGEsIGFkZCB0byBtYXRjaCBsaXN0DQpgYGB7cn0NCg0KSVBDX1JfdG90YWxSTkEgPC0gdG90YWxSTkFfc3VtWywgYygxLDIsNCldDQppcGNfUl9tYXRjaF9saXN0IDwtIG1lcmdlKGlwY19SX21hdGNoX2xpc3QsIElQQ19SX3RvdGFsUk5BLCBieSA9ICJtUk5BIiwgLmtlZXBfYWxsID0gVFJVRSkNCm5hbWVzKGlwY19SX21hdGNoX2xpc3QpW25hbWVzKGlwY19SX21hdGNoX2xpc3QpID09ICdJUENfUl9zdW0nXSA8LSAnbVJOQV9jb3VudCcNCmlwY19SX21hdGNoX2xpc3QkY2VsbF9saW5lIDwtICJJUENfUiINCmlwY19SX21hdGNoX2xpc3QkdHJlYXRtZW50IDwtICJyZXNpc3RhbnQiDQppcGNfUl9tYXRjaF9saXN0IDwtIGlwY19SX21hdGNoX2xpc3RbLCBjKDksMTAsMywxLDcsNCwyLDUsOCw2KV0NCiNzYXZlUkRTKGlwY19SX21hdGNoX2xpc3QsICJJUENfUl9kYXRhLlJEUyIpDQoNCnNrX1JfdG90YWxSTkEgPC0gdG90YWxSTkFfc3VtWywgYygxLDIsOCldDQpza19SX21hdGNoX2xpc3QgPC0gbWVyZ2Uoc2tfUl9tYXRjaF9saXN0LCBza19SX3RvdGFsUk5BLCBieSA9ICJtUk5BIiwgLmtlZXBfYWxsID0gVFJVRSkNCm5hbWVzKHNrX1JfbWF0Y2hfbGlzdClbbmFtZXMoc2tfUl9tYXRjaF9saXN0KSA9PSAnU0tfUl9zdW0nXSA8LSAnbVJOQV9jb3VudCcNCnNrX1JfbWF0Y2hfbGlzdCRjZWxsX2xpbmUgPC0gIlNLX1IiDQpza19SX21hdGNoX2xpc3QkdHJlYXRtZW50IDwtICJyZXNpc3RhbnQiDQpza19SX21hdGNoX2xpc3QgPC0gc2tfUl9tYXRjaF9saXN0WywgYyg5LDEwLDMsMSw3LDQsMiw1LDgsNildDQojc2F2ZVJEUyhza19SX21hdGNoX2xpc3QsICJTS19SX2RhdGEuUkRTIikNCmBgYA0KDQoNCiMgTWVyZ2UgYWxsIGRhdGFmcmFtZXMgdG8gY3JlYXRlIGEgc2luZ3VsYXIgY291bnQgdGFibGUgb2YgYWxsIGNlbGwgbGluZXMgYW5kIHRyZWF0bWVudHMNCmBgYHtyfQ0KI1NLX1JfZGF0YSA8LSByZWFkUkRTKCJTS19SX2RhdGEucmRzIikNCiNTS19kYXRhIDwtIHJlYWRSRFMoIlNLX2RhdGEucmRzIikNCiNJUENfUl9kYXRhIDwtIHJlYWRSRFMoIklQQ19SX2RhdGEucmRzIikNCiNJUENfZGF0YSA8LSByZWFkUkRTKCJJUENfZGF0YS5yZHMiKQ0KI01KX2RhdGEgPC0gcmVhZFJEUygiTUpfZGF0YS5SRFMiKQ0KI2NvdW50X2RhdGEgPC0gcmJpbmQoU0tfUl9kYXRhLCBTS19kYXRhLCBJUENfUl9kYXRhLCBJUENfZGF0YSwgTUpfZGF0YSkNCg0KY291bnRfZGF0YSA8LSByYmluZChza19SX21hdGNoX2xpc3QsIHNrX21hdGNoX2xpc3QsIGlwY19SX21hdGNoX2xpc3QsIGlwY19tYXRjaF9saXN0LCBtal9tYXRjaF9saXN0KQ0KDQojc2F2ZVJEUyhjb3VudF9kYXRhLCAidG90YWxfY291bnRfZGF0YS5yZHMiKQ0KYGBgDQoNCiMgQ3JlYXRlIGEgY291bnQgb2Ygd2hldGhlciBoeWJyaWRzIGFyZSBzZWVuIGluIHRyaXBsaWNhdGVzLCBkdXBsaWNhdGVzLCBvciBhcyB1bmlxdWUgaHlicmlkcw0KYGBge3J9DQpxQ0xBU0ggPC0gYmluZF9yb3dzKHJlYWRSRFMoaGVyZTo6aGVyZSgiaW5pdGlhbF9kYXRhL2h5Yl9zZW5zaXRpdmUucmRzIikpICU+JSANCiAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUoY29uZGl0aW9uPSJzZW5zaXRpdmUiKSAsDQogICAgICAgICAgICAgICAgICAgIHJlYWRSRFMoaGVyZTo6aGVyZSgiaW5pdGlhbF9kYXRhL2h5Yl9yZXNpc3RhbnQucmRzIikpICU+JSANCiAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUoY29uZGl0aW9uPSJyZXNpc3RhbnQiKSkNCg0KDQpjb3VudHNfcmVwbGljYXRlcyA8LSBxQ0xBU0ggJT4lIA0KICBncm91cF9ieShjb25kaXRpb24sIGNlbGxfbGluZSwgaHlicmlkcykgJT4lIA0KICBzdW1tYXJpc2UocmVwbGljYXRlcyA9IGxpc3QoU2FtcGxlICU+JSB1bmlxdWUoKSksIG1pUk5BLCBtUk5BICkgJT4lDQogIG11dGF0ZSh0b3RhbCA9IG1hcF9pbnQoIHJlcGxpY2F0ZXMsIGxlbmd0aCkpICU+JQ0KICBkaXN0aW5jdCgpICU+JSANCiAgbXV0YXRlKGluX3RyaXBsaWNhdGVzID0gZmFjdG9yKGlmZWxzZSh0b3RhbD09MywgIlRyaXBsaWNhdGVzIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh0b3RhbD09MiwgIkR1cGxpY2F0ZXMiLCAiVW5pcXVlIikpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJVbmlxdWUiLCAiRHVwbGljYXRlcyIsICJUcmlwbGljYXRlcyIpKSkgJT4lDQogIGFycmFuZ2UoY29uZGl0aW9uLCBjZWxsX2xpbmUsIGh5YnJpZHMsIGluX3RyaXBsaWNhdGVzKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgIHVuZ3JvdXAoKSAlPiUNCiAgcmlnaHRfam9pbihjb3VudF9kYXRhLCBieT1jKCJjZWxsX2xpbmUiLCAiaHlicmlkcyIsICJtUk5BIiwgIm1pUk5BIikpDQoNCmBgYA0KDQojIENyZWF0ZSBhIDNEIFJlcHJlc2VudGF0aW9uIG9mIHRoZSBsb2cgVmFsdWUgb2YgQ291bnRzDQpgYGB7cn0NCmZpZyA8LSBwbG90X2x5KGNvdW50X2RhdGEsIHggPSB+bG9nKG1STkFfY291bnQpLCB5ID0gfmxvZyhoeWJyaWRfY291bnQpLCB6ID0gfmxvZyhtaVJOQV9jb3VudCksIGNvbG9yID0gfmNlbGxfbGluZSwgY29sb3JzID0gYygnZG9kZ2VyYmx1ZTQnLCAnZGFya3NsYXRlZ3JheTQnLCdkYXJrZ3JlZW4nLCAnZmlyZWJyaWNrJywgJ2RhcmtzYWxtb24nKSkNCmZpZyA8LSBmaWcgJT4lIGFkZF9tYXJrZXJzKCkNCmZpZyA8LSBmaWcgJT4lIGxheW91dChzY2VuZSA9IGxpc3QoeGF4aXMgPSBsaXN0KHRpdGxlID0gJ0xvZyhtUk5BIENvdW50KScpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAnTG9nKEh5YnJpZCBDb3VudCknKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgemF4aXMgPSBsaXN0KHRpdGxlID0gJ0xvZyhtaVJOQSBDb3VudCknKSksDQogICAgICAgICAgICAgICAgICAgICAgdGl0bGU9J0NvcnJlbGF0aW9uIEFuYWx5c2lzJykNCg0KZmlnDQpodG1sd2lkZ2V0czo6c2F2ZVdpZGdldChwbG90bHk6OmFzX3dpZGdldChmaWcpLCAgIi4vcmVzdWx0cy9xQ0xBU0hfdG90X1JOQXNlcV9zcGF0aWFsX3JlcHJlc2VudGF0aW9uLmh0bWwiKQ0KYGBgDQoNCg0KDQpgYGB7cn0NCnAgPC0gY291bnRzX3JlcGxpY2F0ZXMgJT4lIA0KICBwbG90bHk6OnBsb3RfbHkoeD1+bG9nKG1STkFfY291bnQpLCB5PX5sb2coaHlicmlkX2NvdW50KSwgej1+bG9nKG1pUk5BX2NvdW50KSwgc2l6ZT0xLCBjb2xvcj1+aW5fdHJpcGxpY2F0ZXMsIHRleHQ9fmh5YnJpZHMsIHR5cGU9InNjYXR0ZXIzZCIsIG1vZGU9Im1hcmtlcnMiKQ0KcA0KaHRtbHdpZGdldHM6OnNhdmVXaWRnZXQocGxvdGx5Ojphc193aWRnZXQocCksICAiLi9yZXN1bHRzL3FDTEFTSF90b3RfUk5Bc2VxX3RyaXBsaWNhdGVzLmh0bWwiKQ0KYGBgDQoNCg0KDQo=